﻿using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Messaging;
using HslCommunication;
using HslCommunication.Profinet.Siemens;
using System;
using System.Text.RegularExpressions;
using System.Windows;
using System.Windows.Media;
using TransControlSystem.Dao;
using TransControlSystem.Model;
using TransControlSystem.Utils;
using TransControlSystem.ViewModel.Common;
using TransControlSystem.ViewModel.Common.Command;

namespace TransControlSystem.ViewModel
{
    public class PlcAddressConfigViewModel : ViewModelBase
    {
        /// <summary>
        /// 本程序默认PLC地址
        /// </summary>
        private PlcAddress DefaultPlcAddress;

        /// <summary>
        /// 隐藏窗体命令
        /// </summary>
        public DelegateCommand HideProgrammableLogicControllerConfigWindowCommand { get; set; }
        /// <summary>
        /// 保存配置命令
        /// </summary>
        public DelegateCommand SaveProgrammableLogicControllerConfigCommand { get; set; }
        /// <summary>
        /// 测试通讯命令
        /// </summary>
        public DelegateCommand TestProgrammableLogicControllerConfigCommand { get; set; }
        /// <summary>
        /// 文本框改变命令
        /// </summary>
        public DelegateCommand TextChangedCommand { get; set; }
        /// <summary>
        /// PLC配置地址
        /// </summary>
        private string _ProgrammableLogicControllerAddress;
        /// <summary>
        /// PLC配置地址
        /// </summary>
        public string ProgrammableLogicControllerAddress
        {
            get { return _ProgrammableLogicControllerAddress; }
            set
            {
                _ProgrammableLogicControllerAddress = value;
                RaisePropertyChanged("ProgrammableLogicControllerAddress");
            }
        }
        /// <summary>
        /// 测试结果颜色
        /// </summary>
        private LinearGradientBrush _TestResultColor;
        /// <summary>
        /// 测试结果颜色
        /// </summary>
        public LinearGradientBrush TestResultColor
        {
            get { return _TestResultColor; }
            set
            {
                _TestResultColor = value;
                RaisePropertyChanged("TestResultColor");
            }
        }
        /// <summary>
        /// 测试结果
        /// </summary>
        private string _TestResultText;
        /// <summary>
        /// 测试结果
        /// </summary>
        public string TestResultText
        {
            get { return _TestResultText; }
            set
            {
                _TestResultText = value;
                RaisePropertyChanged("TestResultText");
            }
        }
        /// <summary>
        /// 保存按钮是否可用
        /// </summary>
        private bool _ButtonSaveIsEnabled;
        /// <summary>
        /// 保存按钮是否可用 
        /// </summary>
        public bool ButtonSaveIsEnabled
        {
            get { return _ButtonSaveIsEnabled; }
            set
            {
                _ButtonSaveIsEnabled = value;
                RaisePropertyChanged("ButtonSaveIsEnabled");
            }
        }
        /// <summary>
        /// 构造函数
        /// </summary>
        public PlcAddressConfigViewModel()
        {
            //初始化隐藏窗体命令
            HideProgrammableLogicControllerConfigWindowCommand = new DelegateCommand()
            {
                ExecuteActionObj = new Action<object>(HideProgrammableLogicControllerConfigWindowHandler)
            };
            //初始化保存配置命令
            SaveProgrammableLogicControllerConfigCommand = new DelegateCommand()
            {
                ExecuteActionObj = new Action<object>(SaveProgrammableLogicControllerConfigHandler)
            };
            //初始化测试通讯命令
            TestProgrammableLogicControllerConfigCommand = new DelegateCommand()
            {
                ExecuteActionObj = new Action<object>(TestProgrammableLogicControllerConfigHandler)
            };
            //初始化文本变更事件命令
            TextChangedCommand = new DelegateCommand()
            {
                ExecuteActionObj = new Action<object>(TextChangedHandler)
            };
            //初始化保存按钮不可用
            ButtonSaveIsEnabled = false;
            //加载默认地址
            LoadDefaultAddress();
            //执行验证
            TextChangedCommand.Execute(null);
        }
        /// <summary>
        /// 加载默认地址
        /// </summary>
        private void LoadDefaultAddress()
        {
            PlcAddress QueryCondition = new PlcAddress
            {
                Id = 1
            };
            DefaultPlcAddress = DapperTools.Query<PlcAddress>("select * from ProgrammableLogicControllerConfig where Id = @Id", QueryCondition);
            Application.Current.Dispatcher.Invoke((Action)delegate ()
            {
                ProgrammableLogicControllerAddress = DefaultPlcAddress.SiemensPlcAddress;
            });
        }
        /// <summary>
        /// 隐藏本窗体命令的处理程序
        /// </summary>
        /// <param name="obj"></param>
        private void HideProgrammableLogicControllerConfigWindowHandler(object obj)
        {
            LoadDefaultAddress();
            //加载默认地址
            Messenger.Default.Send<NotificationMessage>(new NotificationMessage(this, "CloseWindowsBoundToProgrammableLogicControllerConfigWindow"));
        }
        /// <summary>
        /// 保存配置命令的处理程序
        /// </summary>
        /// <param name="obj"></param>
        private void SaveProgrammableLogicControllerConfigHandler(object obj)
        {
            if (ButtonSaveIsEnabled)
            {
                if (XyhUtils.IsHasSQLInject(ProgrammableLogicControllerAddress))
                {
                    WindowManager.ShowWarning("警告", "PLC地址不可使用包含SQL注入关键词进行保存操作！");
                }
                else
                {
                    DefaultPlcAddress.SiemensPlcAddress = ProgrammableLogicControllerAddress;
                    int result = DapperTools.Update<PlcAddress>("update ProgrammableLogicControllerConfig set SiemensPlcAddress = @SiemensPlcAddress where Id = @Id", DefaultPlcAddress);
                    if (result > 0)
                    {
                        Messenger.Default.Send<NotificationMessage>(new NotificationMessage(this, "CloseWindowsBoundToProgrammableLogicControllerConfigWindow"));
                        WindowManager.ShowWarning("提示", "保存PLC地址成功！");
                    }
                }
            }
        }
        /// <summary>
        /// 测试通讯命令的处理程序
        /// </summary>
        /// <param name="obj"></param>
        private void TestProgrammableLogicControllerConfigHandler(object obj)
        {
            if (ProgrammableLogicControllerAddress != null && ProgrammableLogicControllerAddress.Trim().Length > 0)
            {
                //验证IPV4/IPV6格式
                if (Regex.IsMatch(ProgrammableLogicControllerAddress, "^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$") || Regex.IsMatch(ProgrammableLogicControllerAddress, "^([\\da-fA-F]{1,4}:){6}((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)|::([\\da−fA−F]1,4:)0,4((25[0−5]|2[0−4]\\d|[01]?\\d\\d?)\\.)3(25[0−5]|2[0−4]\\d|[01]?\\d\\d?)|::([\\da−fA−F]1,4:)0,4((25[0−5]|2[0−4]\\d|[01]?\\d\\d?)\\.)3(25[0−5]|2[0−4]\\d|[01]?\\d\\d?)|^([\\da-fA-F]{1,4}:):([\\da-fA-F]{1,4}:){0,3}((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)|([\\da−fA−F]1,4:)2:([\\da−fA−F]1,4:)0,2((25[0−5]|2[0−4]\\d|[01]?\\d\\d?)\\.)3(25[0−5]|2[0−4]\\d|[01]?\\d\\d?)|([\\da−fA−F]1,4:)2:([\\da−fA−F]1,4:)0,2((25[0−5]|2[0−4]\\d|[01]?\\d\\d?)\\.)3(25[0−5]|2[0−4]\\d|[01]?\\d\\d?)|^([\\da-fA-F]{1,4}:){3}:([\\da-fA-F]{1,4}:){0,1}((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)|([\\da−fA−F]1,4:)4:((25[0−5]|2[0−4]\\d|[01]?\\d\\d?)\\.)3(25[0−5]|2[0−4]\\d|[01]?\\d\\d?)|([\\da−fA−F]1,4:)4:((25[0−5]|2[0−4]\\d|[01]?\\d\\d?)\\.)3(25[0−5]|2[0−4]\\d|[01]?\\d\\d?)|^([\\da-fA-F]{1,4}:){7}[\\da-fA-F]{1,4}|:((:[\\da−fA−F]1,4)1,6|:)|:((:[\\da−fA−F]1,4)1,6|:)|^[\\da-fA-F]{1,4}:((:[\\da-fA-F]{1,4}){1,5}|:)|([\\da−fA−F]1,4:)2((:[\\da−fA−F]1,4)1,4|:)|([\\da−fA−F]1,4:)2((:[\\da−fA−F]1,4)1,4|:)|^([\\da-fA-F]{1,4}:){3}((:[\\da-fA-F]{1,4}){1,3}|:)|([\\da−fA−F]1,4:)4((:[\\da−fA−F]1,4)1,2|:)|([\\da−fA−F]1,4:)4((:[\\da−fA−F]1,4)1,2|:)|^([\\da-fA-F]{1,4}:){5}:([\\da-fA-F]{1,4})?|([\\da−fA−F]1,4:)6:|([\\da−fA−F]1,4:)6:"))
                {
                    //西门子对象
                    SiemensS7Net siemens = new SiemensS7Net(SiemensPLCS.S1500, ProgrammableLogicControllerAddress);
                    //PLC连接对象
                    OperateResult connectPlc = siemens.ConnectServer();
                    if (connectPlc.IsSuccess)
                    {
                        Application.Current.Dispatcher.Invoke((Action)delegate ()
                        {
                            ButtonSaveIsEnabled = true;
                            LinearGradientBrush linearGradientBrush = new LinearGradientBrush();
                            linearGradientBrush.StartPoint = new Point(0, 0);
                            linearGradientBrush.EndPoint = new Point(0, 1);
                            linearGradientBrush.GradientStops.Add(new GradientStop(Color.FromRgb(0, 238, 0), 0.0));
                            linearGradientBrush.GradientStops.Add(new GradientStop(Color.FromRgb(0, 238, 0), 1.0));
                            TestResultColor = linearGradientBrush;
                            TestResultText = "通讯测试成功，请保存！";
                        });
                    }
                    else
                    {
                        Application.Current.Dispatcher.Invoke((Action)delegate ()
                        {
                            ButtonSaveIsEnabled = false;
                            LinearGradientBrush linearGradientBrush = new LinearGradientBrush();
                            linearGradientBrush.StartPoint = new Point(0, 0);
                            linearGradientBrush.EndPoint = new Point(0, 1);
                            linearGradientBrush.GradientStops.Add(new GradientStop(Color.FromRgb(255, 0, 0), 0.0));
                            linearGradientBrush.GradientStops.Add(new GradientStop(Color.FromRgb(255, 0, 0), 1.0));
                            TestResultColor = linearGradientBrush;
                            TestResultText = "通讯测试失败，请修改！";
                        });
                    }
                }
                else
                {
                    WindowManager.ShowWarning("警告", "您输入PLC地址格式不正确,请修改后重试！");
                }
            }
            else
            {
                Application.Current.Dispatcher.Invoke((Action)delegate ()
                {
                    ButtonSaveIsEnabled = false;
                });
                WindowManager.ShowWarning("警告", "请输入PLC地址！");
            }
        }

        /// <summary>
        /// 文本改变命令的处理程序
        /// </summary>
        /// <param name="obj"></param>
        private void TextChangedHandler(object obj)
        {
            Application.Current.Dispatcher.Invoke((Action)delegate ()
            {
                ButtonSaveIsEnabled = false;
            });
            //验证IPV4/IPV6格式
            if (Regex.IsMatch(ProgrammableLogicControllerAddress, "^((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)$") || Regex.IsMatch(ProgrammableLogicControllerAddress, "^([\\da-fA-F]{1,4}:){6}((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)|::([\\da−fA−F]1,4:)0,4((25[0−5]|2[0−4]\\d|[01]?\\d\\d?)\\.)3(25[0−5]|2[0−4]\\d|[01]?\\d\\d?)|::([\\da−fA−F]1,4:)0,4((25[0−5]|2[0−4]\\d|[01]?\\d\\d?)\\.)3(25[0−5]|2[0−4]\\d|[01]?\\d\\d?)|^([\\da-fA-F]{1,4}:):([\\da-fA-F]{1,4}:){0,3}((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)|([\\da−fA−F]1,4:)2:([\\da−fA−F]1,4:)0,2((25[0−5]|2[0−4]\\d|[01]?\\d\\d?)\\.)3(25[0−5]|2[0−4]\\d|[01]?\\d\\d?)|([\\da−fA−F]1,4:)2:([\\da−fA−F]1,4:)0,2((25[0−5]|2[0−4]\\d|[01]?\\d\\d?)\\.)3(25[0−5]|2[0−4]\\d|[01]?\\d\\d?)|^([\\da-fA-F]{1,4}:){3}:([\\da-fA-F]{1,4}:){0,1}((25[0-5]|2[0-4]\\d|[01]?\\d\\d?)\\.){3}(25[0-5]|2[0-4]\\d|[01]?\\d\\d?)|([\\da−fA−F]1,4:)4:((25[0−5]|2[0−4]\\d|[01]?\\d\\d?)\\.)3(25[0−5]|2[0−4]\\d|[01]?\\d\\d?)|([\\da−fA−F]1,4:)4:((25[0−5]|2[0−4]\\d|[01]?\\d\\d?)\\.)3(25[0−5]|2[0−4]\\d|[01]?\\d\\d?)|^([\\da-fA-F]{1,4}:){7}[\\da-fA-F]{1,4}|:((:[\\da−fA−F]1,4)1,6|:)|:((:[\\da−fA−F]1,4)1,6|:)|^[\\da-fA-F]{1,4}:((:[\\da-fA-F]{1,4}){1,5}|:)|([\\da−fA−F]1,4:)2((:[\\da−fA−F]1,4)1,4|:)|([\\da−fA−F]1,4:)2((:[\\da−fA−F]1,4)1,4|:)|^([\\da-fA-F]{1,4}:){3}((:[\\da-fA-F]{1,4}){1,3}|:)|([\\da−fA−F]1,4:)4((:[\\da−fA−F]1,4)1,2|:)|([\\da−fA−F]1,4:)4((:[\\da−fA−F]1,4)1,2|:)|^([\\da-fA-F]{1,4}:){5}:([\\da-fA-F]{1,4})?|([\\da−fA−F]1,4:)6:|([\\da−fA−F]1,4:)6:"))
            {
                Application.Current.Dispatcher.Invoke((Action)delegate ()
                {
                    LinearGradientBrush linearGradientBrush = new LinearGradientBrush();
                    linearGradientBrush.StartPoint = new Point(0, 0);
                    linearGradientBrush.EndPoint = new Point(0, 1);
                    linearGradientBrush.GradientStops.Add(new GradientStop(Color.FromRgb(0, 0, 255), 0.0));
                    linearGradientBrush.GradientStops.Add(new GradientStop(Color.FromRgb(0, 0, 255), 1.0));
                    TestResultColor = linearGradientBrush;
                    TestResultText = "格式正确，请点击通讯测试！";
                });
            }
            else
            {
                Application.Current.Dispatcher.Invoke((Action)delegate ()
                {
                    LinearGradientBrush linearGradientBrush = new LinearGradientBrush();
                    linearGradientBrush.StartPoint = new Point(0, 0);
                    linearGradientBrush.EndPoint = new Point(0, 1);
                    linearGradientBrush.GradientStops.Add(new GradientStop(Color.FromRgb(255, 0, 0), 0.0));
                    linearGradientBrush.GradientStops.Add(new GradientStop(Color.FromRgb(255, 0, 0), 1.0));
                    TestResultColor = linearGradientBrush;
                    TestResultText = "格式不正确，请修改！";
                });
            }
        }
    }
}
